use axum::{routing::get, Router};
use cassie_core::config::config::ApplicationConfig;
use cassie_core::fundation::{AppContext, ApplicationContext};
use cassie_http::init_context;
use log::info;
use micro_engine::ext::http::default_router;
use std::net::SocketAddr;
use std::str::FromStr;

///*description:The main program entry starts to specify the configuration file
///*author:cassie-lxd<348040933@qq.com>
#[tokio::main]
async fn main() {
  //init webContext
  init_context().await;
  // Run the HTTP server and handle any errors
  if let Err(e) = run_http().await {
    eprintln!("Error running HTTP server: {}", e);
    std::process::exit(1);
  }
}

///start server
async fn run_http() -> Result<(), Box<dyn std::error::Error>> {
  let default_addr = "127.0.0.1:20003";
  let mut addr = get_socket_addr(default_addr)?;

  if let Some(cof) = ApplicationContext::get_service::<ApplicationConfig>() {
    let cassie_config = cof.lock().unwrap();
    let server = cassie_config.server().clone();
    drop(cassie_config); // Release the lock immediately after use

    let host = server.host();
    let port = server.port().unwrap_or(20003);
    addr = get_socket_addr(&format!("{}:{}", host, port))?;
  }

  info!(" - Local:   http://{}", addr);
  let app = Router::new().route("/", get(root)).fallback(default_router);
  axum::Server::bind(&addr).serve(app.into_make_service()).await?;

  Ok(())
}

fn get_socket_addr(addr: &str) -> Result<SocketAddr, Box<dyn std::error::Error>> {
  SocketAddr::from_str(addr).map_err(|e| e.into())
}
async fn root() -> &'static str {
  "Hello, World!"
}
